#ifndef COMMON_THREAD_H_
#define COMMON_THREAD_H_
// std or system
#include <pthread.h>

namespace thread {

	/*! \class Thread
	  \brief A base thread wrapper
	 *
	 *  A simple base wrapper class for pthread
	 *  This base class provides flexibility for
	 *  users to override the Run interface to
	 *  implement their own logic.
	 */
	class Thread
	{
		public:

			/**
			 * Thread constructor
			 */
			Thread();

			/**
			 * Thread destructor
			 * virtual for further inheritance
			 */
			virtual ~Thread();

			/**
			 * Get this thread's thread id
			 * @return  thread id
			 */
			inline pthread_t thread_id() const
			{
				return thread_id_;
			}

			/**
			 * Make thread Run
			 * @return If successful, return zero; otherwise, an error
			 *         number shall be returned to indicate the error
			 */
			int Start();

			/**
			 * Make a flag to tell the thread stop running
			 */
			inline void set_stop()
			{
				stop_ = true;
			}

			/**
			 * Check if the thread should stop running
			 */
			inline bool stop() const
			{
				return stop_;
			}

			/*
			 *  Make a flag to tell the thread release thread class
			 */
			inline void set_release()
			{
				release_ = true;
			}

			/*
			 *  thr thread detach self
			 */
			inline void Detach()
			{
				pthread_detach(thread_id_);
			}

			/**
			 * Wait the thread to exit
			 */
			void Join();

			/**
			 * To check if the thread is still live
			 * @return true for live, false for dead
			 */
			inline bool alive() const
			{
				return alive_;
			}

		protected:

			/**
			 * Override this virtual function to implement your own logic
			 */
			virtual void Run() = 0;

		private:

			/// disable some constructors and assignment operators
			Thread(const Thread& thr);
			Thread& operator = (const Thread& thr);

			/// thread start routine
			static void* ThreadProc(void* arg);

		protected:

			bool      alive_;        ///< if the thread is still alive?
			bool      stop_;         ///< tell the thread to stop, reserved for future extension
			pthread_t thread_id_;    ///< thread id
			bool      release_;      ///< tell the thread to release thread class

	};

}

#endif // YY_COMMON_THREAD_H_

